#include "stm32f4xx.h"
#include "delay.h"

#define SYSTEM_CLK 168000000             // 定义系统时钟频率为168MHz
static volatile double runtime_us = 0; // 64位运行时间累计变量(微秒级)
static uint32_t last_reload = 0;         // 记录上次重装载值

// SysTick初始化函数
void SysTick_Init(void)
{
    SysTick->LOAD = (SYSTEM_CLK / 1000) - 1;    // 配置1ms定时重装载值
    SysTick->VAL = 0;                           // 清空当前计数值
    SysTick->CTRL = SysTick_CTRL_ENABLE_Msk |   // 使能SysTick
                    SysTick_CTRL_CLKSOURCE_Msk; // 选择处理器时钟源
    last_reload = SysTick->LOAD;                // 保存初始重装载值
}

// 更新时间累计值(内部使用)
static void Update_Runtime(void)
{
    uint32_t current = SysTick->VAL; // 获取当前计数值
    // 计算从上一次读取到现在的计数值变化量
    uint32_t elapsed = (last_reload - current) % (last_reload + 1);
    // 将时钟周期数转换为微秒并累加
    runtime_us += (double)(elapsed * 1000) / (SYSTEM_CLK / 1000);
    last_reload = current; // 更新最后记录值
}

// 获取系统运行时间(微秒)
uint64_t Get_Runtime_us(void)
{
    Update_Runtime();  // 先更新时间累计
    return runtime_us; // 返回累计微秒数
}

// 获取当前tick(毫秒)
uint32_t Get_Tick_ms(void)
{
    return Get_Runtime_us() / 1000; // 微秒转毫秒
}

// 获取当前tick(微秒)
uint32_t Get_Tick_us(void)
{
    return Get_Runtime_us() % 1000; // 取微秒部分
}

// 毫秒级延时
void Delay_ms(uint32_t ms)
{
    uint64_t target = Get_Runtime_us() + ms * 1000; // 计算目标时间
    while (Get_Runtime_us() < target)
        ; // 阻塞等待
}

// 微秒级延时
void Delay_us(uint32_t us)
{
    uint64_t target = Get_Runtime_us() + us; // 计算目标时间
    while (Get_Runtime_us() < target)
        ; // 阻塞等待
}

